import 'dart:collection';
import 'dart:math' as math;

import 'package:faker/models/rss.dart';
import 'package:faker/provider/favorite_rss_provider.dart';
import 'package:faker/provider/readlater_rss_provider.dart';
import 'package:faker/res/style.dart';
import 'package:faker/utils/toast_util.dart';
import 'package:faker/widgets/base_widget.dart';
import 'package:faker/widgets/item_rssdetail_list.dart';
import 'package:faker/widgets/loading_dialog.dart';
import 'package:faker/widgets/refresh_helper.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:webfeed/webfeed.dart';

import '../i18n/i18n.dart';

class RssDetail extends BaseWidget {
  final String route;
  final String title;

  RssDetail({Key key, @required this.route, @required this.title});

  @override
  _RssDetailState createState() => _RssDetailState();

  @override
  BaseWidgetState<BaseWidget> attachState() {
    // TODO: implement attachState
    return null;
  }
}

class _RssDetailState extends BaseWidgetState<RssDetail> {
  ///浮动标题
  bool floating = false;
  bool snap = false;
  bool pinned = false;

  /// 是否显示悬浮按钮
  bool _isShowFAB = true;

  List<RssBean> rssitems = new List();
  Map<String, bool> fav = new HashMap<String, bool>();
  Map<String, bool> rdl = new HashMap<String, bool>();

  /// listview 控制器
  ScrollController _scrollController = new ScrollController();

  /// 下拉刷新控制器
  RefreshController _refreshController =
      new RefreshController(initialRefresh: false);

  /// ListView Item 左右滑动;
  final SlidableController slidableController = SlidableController();

  int cnt = 0;

  /// getRss Data
  Future getRssData() async {
    rssitems.clear();
    fav.clear();
    rdl.clear();
    RssBean rssFeed = await RssModel().getRss(widget.route);
    cnt = rssFeed.items.length;
    await Future.forEach(rssFeed.items, (item) async {
      bool b = await checkFav(item.guid);
      bool c = await checkRdl(item.guid);
      fav[item.guid] = b;
      rdl[item.guid] = c;
    });
    if (rssFeed != null) {
      showContent().then((value) {
        _refreshController.refreshCompleted(resetFooterState: true);
        setState(() {
          rssitems.add(rssFeed);
        });
      });
    } else {
      showEmpty();
    }
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    showLoading().then((value) {
      getRssData();
    });

    _scrollController.addListener(() {
      /// 滑动到底部，加载更多
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        // getMoreNoTodoList();
      }
      if (_scrollController.offset < 200 && _isShowFAB) {
        setState(() {
          _isShowFAB = false;
        });
      } else if (_scrollController.offset >= 200 && !_isShowFAB) {
        setState(() {
          _isShowFAB = true;
        });
      }
    });
  }

  @override
  void initState() {
    super.initState();
    setAppBarVisible(true);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        height: MediaQuery.of(context).size.height,
        color: Theme.of(context).backgroundColor,
        child: SmartRefresher(
          enablePullDown: true,
          enablePullUp: false,
          header: MaterialClassicHeader(),
          footer: RefreshFooter(),
          controller: _refreshController,
          onRefresh: getRssData,
          onLoading: getRssData,
          child: CustomScrollView(
            physics: ScrollPhysics(),
            slivers: <Widget>[
              SliverPersistentHeader(
                pinned: false,
                floating: true,
                delegate: _SliverAppBarDelegate(
                  minHeight: 0.0,
                  maxHeight: 120.0,
                  child: Container(
                    decoration: BoxDecoration(
                      borderRadius:
                          new BorderRadius.all(new Radius.circular(5.0)),
                      image: DecorationImage(
                        image: AssetImage("assets/images/image_04.jpg"),
                        fit: BoxFit.cover,
                      ),
                    ),
                    alignment: Alignment(0.0, 0.4),
                    child: Text(
                      widget.title,
                      textAlign: TextAlign.center,
                      style: TextStyle(
                        color: Theme.of(context).textSelectionColor,
                        fontSize: 46.0,
                        fontFamily: fontName,
                        letterSpacing: 1.0,
                        decoration: TextDecoration.none,
                      ),
                    ),
                  ),
                ),
              ),
              SliverToBoxAdapter(
                child: SizedBox(
                  height: 20,
                  child: Container(
                    color: Theme.of(context).backgroundColor,
                    width: 20.0,
                  ),
                ),
              ),
              SliverList(
                delegate: SliverChildBuilderDelegate(
                  (BuildContext context, int index) {
                    return itemView(context, index);
                  },
                  childCount: cnt,
                ),
              ),
            ],
          ),
        ));
  }

  checkFav(String guid) async {
    FavRssProvider provider = new FavRssProvider();
    final bool ret = await provider.checkFav(guid);
    return ret;
  }

  checkRdl(String guid) async {
    bool ret = await new ReadLaterRssProvider().checkRdl(guid);
    return ret;
  }

  itemView(BuildContext context, int index) {
    RssItem item = rssitems[0].items[index];
    return RssDetailsList(
      item: item,
      fav: fav[item.guid] != null ? fav[item.guid] : false,
      mark: rdl[item.guid] != null ? rdl[item.guid] : false,
      slidableController: slidableController,
      addToCollection: (item, tag) async {
        switch (tag) {
          case false:
            FavRssProvider provider = new FavRssProvider();
            var ret = provider.insert(item);
            ret.then((value) {
              if (value > 0) {
                T.show(msg: S.of(context).successAddtoFav);
              } else {
                T.show(msg: S.of(context).failedAddtoFav);
              }
            });
            break;
          case true:
            FavRssProvider provider = new FavRssProvider();
            await provider.delete(item.guid);
            T.show(msg: S.of(context).successCancled);
            break;
        }
      },
      readLater: (item, tag) async {
        switch (tag) {
          case false:
            ReadLaterRssProvider provider = new ReadLaterRssProvider();
            var ret = provider.insert(item);
            ret.then((value) {
              if (value > 0) {
                T.show(msg: S.of(context).successAddtoRdl);
              } else {
                T.show(msg: S.of(context).failedAddtoFav);
              }
            });
            break;
          case true:
            ReadLaterRssProvider provider = new ReadLaterRssProvider();
            await provider.delete(item.guid);
            T.show(msg: S.of(context).successCancled);
            break;
        }
      },
    );
  }

  @override
  AppBar attachAppBar() {
    // TODO: implement attachAppBar
    return null;
  }

  @override
  void dispose() {
    _refreshController.dispose();
    _scrollController.dispose();
    super.dispose();
  }

  /// 显示Loading
  _showLoading(BuildContext context) {
    showDialog(
        context: context,
        barrierDismissible: false,
        builder: (_) {
          return new LoadingDialog(
            outsideDismiss: false,
            loadingText: S.of(context).onLoading,
          );
        });
  }

  @override
  Widget attachContentWidget(BuildContext context) {
    // TODO: implement attachContentWidget
    return null;
  }

  @override
  void onClickErrorWidget() {
    // TODO: implement onClickErrorWidget
  }
}

class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
  _SliverAppBarDelegate({
    @required this.minHeight,
    @required this.maxHeight,
    @required this.child,
  });

  final double minHeight;
  final double maxHeight;
  final Widget child;

  @override
  double get minExtent => minHeight;

  @override
  double get maxExtent => math.max(maxHeight, minHeight);

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return new SizedBox.expand(child: child);
  }

  @override
  bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
    return maxHeight != oldDelegate.maxHeight ||
        minHeight != oldDelegate.minHeight ||
        child != oldDelegate.child;
  }
}
